package com.blockmeta.bbs.businesslibrary.util;

import com.blankj.utilcode.util.LogUtils;

import com.blockmeta.bbs.baselibrary.provider.IApplicationProvider;
import com.blockmeta.bbs.businesslibrary.arouter.RouterHelper;
import com.blockmeta.bbs.businesslibrary.arouter.RouterPath;
import com.blockmeta.bbs.businesslibrary.net.retrofit.RetrofitFactory;
import com.blockmeta.bbs.businesslibrary.net.retrofit.api.InterfaceReportIssue;
import com.blockmeta.bbs.businesslibrary.net.retrofit.api.InterfaceReportSample;
import com.blockmeta.bbs.businesslibrary.pojo.reportissue.Issue;
import com.blockmeta.bbs.businesslibrary.pojo.reportissue.Tags;

import org.jetbrains.annotations.NotNull;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.concurrent.atomic.AtomicBoolean;

import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;

public class ReportIssue {

    public static final int ENOUGH_ISSUE_COUNT = 50;
//    static final String ABNORMAlHTTPCODE = "app_http_code_exception";
    static final String RESPONSEDATAERROR = "app_response_data_exception";
    static final String RESPONSETIME = "app_response_time_code";
    public static final int ENOUGH_TIME = 60;
    public static int SAMPLE_MAX = 10000;
    public static int SAMPLE = SAMPLE_MAX;

    static List<Issue> issues = new ArrayList<>();
    static AtomicBoolean reporting = new AtomicBoolean(false);
    static long lastReportTime = System.currentTimeMillis() / 1000;

    public static synchronized void recordHttpCostIssue(Integer value, Integer code, String host, String path) {
        Issue issue = getIssue(host, path, RESPONSETIME, "histogram");
        issue.getTags().setStatus(code);
        issue.setValue(Collections.singletonList(value));
        issues.add(issue);
        sendIssueIfEnough();
    }

    private static boolean isDoSample() {
        Random random = new Random();
        int randomInt = random.nextInt(SAMPLE_MAX);
        return randomInt < SAMPLE;
    }


    public static synchronized void recordHttpErrorIssue(Integer code, String host, String path) {

    }

    public static synchronized void recordHttpParseErrorIssue(String host, String path) {
        Issue issue = getIssue(host, path, RESPONSEDATAERROR, "counter");
        issue.setValue(Collections.singletonList(1));
        issues.add(issue);
        sendIssueIfEnough();
    }

    private static void sendIssueIfEnough() {
        if (issues.size() > ENOUGH_ISSUE_COUNT || ((System.currentTimeMillis() / 1000) - lastReportTime > ENOUGH_TIME)) {
            try {
                sendIssues(false);
            }
            catch (Exception e){
                LogUtils.d("author" + "sendIssueIfEnough" + e.getMessage());

            }
        }
    }


    @NotNull
    private static Issue getIssue(String host, String path, String metric, String type) {
        Tags tags = new Tags();
        tags.setOs("android");
        IApplicationProvider provider = RouterHelper.getProvider(RouterPath.APPLICATION_PROVIDER);
        tags.setApp(AppCode.getMyAppCode(provider.getProjectBuildInfo().application_id));
        tags.setVersion(provider.getProjectBuildInfo().version_name);
        tags.setHost(host);
        tags.setPath(path);
        Issue issue = new Issue();
        issue.setMetric(metric);
        issue.setTimestamp((int) (System.currentTimeMillis() / 1000));
        issue.setTags(tags);
        issue.setType(type);
        return issue;
    }


    public static void getSample() {
        Retrofit retrofit = RetrofitFactory.getRootRetrofit();
        InterfaceReportSample reportIssue = retrofit.create(InterfaceReportSample.class);
        Call<ResponseBody> call = reportIssue.getSample();
        LogUtils.d("author" + "getSample success" + call);
        call.enqueue(new Callback<ResponseBody>() {

            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                try {
                    JSONObject jsonObject = null;
                    String responseStr = response.body().string();
                    LogUtils.d("author" + "reportissue success" + responseStr);
                    jsonObject = new JSONObject(responseStr);
                    SAMPLE = jsonObject.getInt("data");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                LogUtils.d("author" + "reportissue fail" + t.getMessage());
            }

        });

    }

    public static void sendIssues(boolean force) {

        //防止请求体过大导致失败
        if (issues.size() > ENOUGH_ISSUE_COUNT * 2) {
            issues.subList(0, issues.size() - ENOUGH_ISSUE_COUNT).clear();
        }

        if (!isDoSample()) {
            resetIssueReportStatus();
            return;
        }

        //防止嵌套调用,直接返回
        if (reporting.get()) return;
        reporting.set(true);
        Retrofit retrofit = RetrofitFactory.getRootRetrofit();
        InterfaceReportIssue reportIssue = retrofit.create(InterfaceReportIssue.class);
        Call<ResponseBody> call = reportIssue.report(issues);
        LogUtils.d("author" + "reportissue success" + call);
        call.enqueue(new Callback<ResponseBody>() {

            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                LogUtils.d("author" + "reportissue success" + response.message());
                resetIssueReportStatus();
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                LogUtils.d("author" + "reportissue fail" + t.getMessage());
                resetIssueReportStatus();
            }

        });
    }

    private static void resetIssueReportStatus() {
        issues.clear();
        reporting.set(false);
        lastReportTime = System.currentTimeMillis() / 1000;
    }
}
